package small.common.core.file.watcher;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import small.common.core.file.event.FileChangeEvent;

import java.io.*;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.charset.StandardCharsets;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;

/**
 * @Author zhoujin
 * @Date 2022/11/9 17:40
 */
public class SimpleFileWatcher extends FileWatcher {

    protected static final Logger LOGGER = LoggerFactory.getLogger(SimpleFileWatcher.class);

    private static final String NO_SPACE_CN = "设备上没有空间";

    private static final String NO_SPACE_EN = "No space left on device";

    private static final String DISK_QUATA_CN = "超出磁盘限额";

    private static final String DISK_QUATA_EN = "Disk quota exceeded";

    @Override
    public void onChange(FileChangeEvent event) {
        LOGGER.info("接收到的事件为{}", event.toString());
        List<String> res = readFile(event.getPaths());
        LOGGER.info("文件内容为{}", res);
    }

    @Override
    public boolean interest(String context) {
        return contains(context, "cluster.conf");
    }

    public static boolean contains(CharSequence seq, CharSequence searchSeq) {
        if (seq != null && searchSeq != null) {
            return indexOf(seq, searchSeq, 0) >= 0;
        } else {
            return false;
        }
    }

    static int indexOf(CharSequence cs, CharSequence searchChar, int start) {
        return cs.toString().indexOf(searchChar.toString(), start);
    }


    /**
     * 读文件
     *
     * @param configFilePath
     * @return
     */
    private List<String> readFile(String configFilePath) {
        String path = Paths.get(configFilePath, "cluster.conf").toString();
        try (Reader reader = new InputStreamReader(new FileInputStream(new File(path)),
                StandardCharsets.UTF_8)) {
            return readLines(reader);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 写文件
     *
     * @param content
     * @throws IOException
     */
    public static void writeClusterConf(String content, String configFilePath) throws IOException {
        String path = Paths.get(configFilePath, "cluster.conf").toString();
        writeFile(new File(path), content.getBytes(StandardCharsets.UTF_8), true);
    }


    public static boolean writeFile(File file, byte[] content, boolean append) {
        try (FileChannel fileChannel = new FileOutputStream(file, append).getChannel()) {
            ByteBuffer buffer = ByteBuffer.wrap(content);
            fileChannel.write(buffer);
            return true;
        } catch (IOException ioe) {
            if (ioe.getMessage() != null) {
                String errMsg = ioe.getMessage();
                if (NO_SPACE_CN.equals(errMsg) || NO_SPACE_EN.equals(errMsg) || errMsg.contains(DISK_QUATA_CN) || errMsg
                        .contains(DISK_QUATA_EN)) {
                    LOGGER.warn("磁盘满，自杀退出");
                    System.exit(0);
                }
            }
        }
        return false;
    }

    /**
     * Read lines.
     *
     * @param input reader
     * @return list of line
     * @throws IOException io exception
     */
    public static List<String> readLines(Reader input) throws IOException {
        BufferedReader reader = toBufferedReader(input);
        List<String> list = new ArrayList<String>();
        String line = null;
        for (; ; ) {
            line = reader.readLine();
            if (null != line && line.length() != 0) {
                list.add(line.trim());
            } else {
                break;
            }
        }
        return list;
    }

    private static BufferedReader toBufferedReader(Reader reader) {
        return reader instanceof BufferedReader ? (BufferedReader) reader : new BufferedReader(reader);
    }
}
